#include <iostream>
using namespace std;

#include <windows.h>
#define VC_EXTRALEAN

//Include our framework class
#include "PaperLuigiFramework.h"

#pragma region Global Variables

HWND g_hWnd;			//This is the handle to a window
HINSTANCE g_hInstance;	//This is a handle to an Instance
bool g_bWindowed;		//Windowed mode or Full-Screen

PaperLuigiFramework game; //An instance of the framework 

#define SCREEN_WIDTH 800	//Screen width for windowed mode
#define SCREEN_HEIGHT 600	//Screen Height for windowed mode
#define WINDOW_TITLE L"Paper Luigi"	//The L allows for the unicode

#pragma endregion

#pragma region Prototypes

//Entry point for our application
int WINAPI wWinMain(HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					LPTSTR lpCmdLine,
					int lpCmdShow);

//Windows procedure, which handles windows messages.
LRESULT CALLBACK WndProc(HWND hWnd,
						 UINT message,
						 WPARAM wparam,
						 LPARAM lparam);
#pragma endregion

//Initialize our window(keeps winmain clean
void InitWindow()
{
	WNDCLASSEX wndClass;
	ZeroMemory(&wndClass, sizeof(WNDCLASSEX));	//Zero's the bits of the structure

	//set up the window variables form WNDCLASSEX
	wndClass.cbSize			= sizeof(WNDCLASSEX);
	wndClass.lpfnWndProc	= (WNDPROC)WndProc;
	wndClass.lpszClassName	= WINDOW_TITLE;
	wndClass.hInstance		= g_hInstance;
	wndClass.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wndClass.hbrBackground	= (HBRUSH)(COLOR_WINDOWFRAME);

	//Register a new type of window
	RegisterClassEx(&wndClass);

	g_hWnd = CreateWindow(
		WINDOW_TITLE, WINDOW_TITLE,		//Window class name and title
		g_bWindowed ? WS_OVERLAPPEDWINDOW | WS_VISIBLE : (WS_POPUP | WS_VISIBLE), //window style
		CW_USEDEFAULT, CW_USEDEFAULT,	//Window position (x,y)
		SCREEN_WIDTH, SCREEN_HEIGHT,	//window width/height
		NULL, NULL,						//Parent Window and Menu
		g_hInstance,					//Handle to the instance
		NULL);

	//Display the window
	ShowWindow(g_hWnd, SW_SHOW);
	UpdateWindow(g_hWnd);
}

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	//set the globals to the values that were sent in
	g_hInstance = hInstance;
	g_bWindowed = true;

	//Initialize and create the window
	InitWindow();

	//Use the MSG structure to catch windows messages
	MSG msg;
	ZeroMemory(&msg, sizeof(MSG));

	//Game Initialization
	game.Initialize(g_hWnd, g_hInstance, g_bWindowed);

	//Windows message loop
	while(msg.message != WM_QUIT)
	{
		//check the message
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		//if the game's device isn't lost
		if(!game.lostDevice())
		{
			//update the game's logic and render
			game.Update();
			game.Render();
		}
	}

	//Game Shutdown
	game.Shutdown();

	//Unregister the window
	UnregisterClass(WINDOW_TITLE, g_hInstance);

	//Successful Shutdown
	return 0;
}

//Windows procedure, which handles windows messages.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
{
	//Attempt to handle windows messages
	switch(message)
	{
	case (WM_PAINT):
		{
			InvalidateRect(hWnd, NULL, TRUE);
			break;
		}
	case (WM_EXITSIZEMOVE):
		{
			game.screenResize();
			break;
		}
	case (WM_DESTROY):
		{
			PostQuitMessage(0);
			break;
		}
	}

	//Pass the message to the default handler
	return DefWindowProc(hWnd, message, wparam, lparam);
}